package dal

import (
	"fmt"
	"time"

	goRedis "github.com/redis/go-redis/v9"

	"gitee.com/cyberocx/rpc-server/biz/conf"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// Dal .
var Dal = _Dal{}

// _Dal .
type _Dal struct {
	Db    *gorm.DB `json:"db"`
	Redis *goRedis.Client
}

// Init .
func Init() {
	Dal.Db = initDb()

	initRedis()
}

// initDb .
func initDb() *gorm.DB {
	db, err := gorm.Open(
		mysql.Open(conf.Config.Dal.DataSource), &gorm.Config{
			Logger: logger.Default.LogMode(logger.Warn), // 输出到stdout
		},
	)
	if err != nil {
		panic(err)
	}

	sqlDB, err := db.DB()
	if err != nil {
		panic(err)
	}
	// SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。
	sqlDB.SetMaxIdleConns(conf.Config.Dal.DbConnPool.SetMaxIdleConns)

	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(conf.Config.Dal.DbConnPool.SetMaxOpenConns)

	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	sqlDB.SetConnMaxLifetime(time.Duration(conf.Config.Dal.DbConnPool.SetConnMaxLifetime) * time.Second)

	return db
}

func initRedis() {
	var rdb *goRedis.Client
	if len(conf.Config.Redis.Sentinel.SentinelAddrs) > 0 {
		// 哨兵模式
		fmt.Println("redis sentinel mode")
		rdb = goRedis.NewFailoverClient(
			&goRedis.FailoverOptions{
				MasterName:       conf.Config.Redis.Sentinel.MasterName,
				SentinelAddrs:    conf.Config.Redis.Sentinel.SentinelAddrs,
				DB:               conf.Config.Redis.Db,
				SentinelPassword: conf.Config.Redis.Sentinel.SentinelPassword,
			},
		)
	} else {
		// 单机模式
		fmt.Println("redis standalone mode")
		rdb = goRedis.NewClient(
			&goRedis.Options{
				Addr:     conf.Config.Redis.Addr,
				Password: conf.Config.Redis.Password, // no password set
				DB:       conf.Config.Redis.Db,       // use default DB
			},
		)
	}

	Dal.Redis = rdb
}
